home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr26 / netprog.zip / NETPROG.TAR / lib / daemon.c next >
C/C++ Source or Header  |  1989-12-17  |  3KB  |  135 lines

  1. /*
  2.  * Initialize a daemon process.
  3.  */
  4.  
  5. #include    <stdio.h>
  6. #include    <signal.h>
  7. #include    <sys/param.h>
  8. #include    <errno.h>
  9. extern int    errno;
  10.  
  11. #ifdef    SIGTSTP        /* true if BSD system */
  12. #include    <sys/file.h>
  13. #include    <sys/ioctl.h>
  14. #endif
  15.  
  16. /*
  17.  * Detach a daemon process from login session context.
  18.  */
  19.  
  20. daemon_start(ignsigcld)
  21. int    ignsigcld;    /* nonzero -> handle SIGCLDs so zombies don't clog */
  22. {
  23.     register int    childpid, fd;
  24.  
  25.     /*
  26.      * If we were started by init (process 1) from the /etc/inittab file
  27.      * there's no need to detach.
  28.      * This test is unreliable due to an unavoidable ambiguity
  29.       * if the process is started by some other process and orphaned
  30.      * (i.e., if the parent process terminates before we are started).
  31.        */
  32.  
  33.     if (getppid() == 1)
  34.           goto out;
  35.  
  36.     /*
  37.      * Ignore the terminal stop signals (BSD).
  38.      */
  39.  
  40. #ifdef SIGTTOU
  41.     signal(SIGTTOU, SIG_IGN);
  42. #endif
  43. #ifdef SIGTTIN
  44.     signal(SIGTTIN, SIG_IGN);
  45. #endif
  46. #ifdef SIGTSTP
  47.     signal(SIGTSTP, SIG_IGN);
  48. #endif
  49.  
  50.     /*
  51.      * If we were not started in the background, fork and
  52.      * let the parent exit.  This also guarantees the first child
  53.      * is not a process group leader.
  54.      */
  55.  
  56.     if ( (childpid = fork()) < 0)
  57.         err_sys("can't fork first child");
  58.     else if (childpid > 0)
  59.         exit(0);    /* parent */
  60.  
  61.     /*
  62.      * First child process.
  63.      *
  64.      * Disassociate from controlling terminal and process group.
  65.      * Ensure the process can't reacquire a new controlling terminal.
  66.      */
  67.  
  68. #ifdef    SIGTSTP        /* BSD */
  69.  
  70.     if (setpgrp(0, getpid()) == -1)
  71.         err_sys("can't change process group");
  72.  
  73.     if ( (fd = open("/dev/tty", O_RDWR)) >= 0) {
  74.         ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling tty */
  75.         close(fd);
  76.     }
  77.  
  78. #else    /* System V */
  79.  
  80.     if (setpgrp() == -1)
  81.         err_sys("can't change process group");
  82.  
  83.     signal(SIGHUP, SIG_IGN);    /* immune from pgrp leader death */
  84.  
  85.     if ( (childpid = fork()) < 0)
  86.         err_sys("can't fork second child");
  87.     else if (childpid > 0)
  88.         exit(0);    /* first child */
  89.  
  90.     /* second child */
  91. #endif
  92.  
  93. out:
  94.     /*
  95.      * Close any open files descriptors.
  96.      */
  97.  
  98.     for (fd = 0; fd < NOFILE; fd++)
  99.         close(fd);
  100.  
  101.     errno = 0;        /* probably got set to EBADF from a close */
  102.  
  103.     /*
  104.      * Move the current directory to root, to make sure we
  105.      * aren't on a mounted filesystem.
  106.      */
  107.  
  108.     chdir("/");
  109.  
  110.     /*
  111.      * Clear any inherited file mode creation mask.
  112.      */
  113.  
  114.     umask(0);
  115.  
  116.     /*
  117.      * See if the caller isn't interested in the exit status of its
  118.      * children, and doesn't want to have them become zombies and
  119.      * clog up the system.
  120.      * With System V all we need do is ignore the signal.
  121.      * With BSD, however, we have to catch each signal
  122.      * and execute the wait3() system call.
  123.      */
  124.  
  125.     if (ignsigcld) {
  126. #ifdef    SIGTSTP
  127.         int    sig_child();
  128.  
  129.         signal(SIGCLD, sig_child);    /* BSD */
  130. #else
  131.         signal(SIGCLD, SIG_IGN);    /* System V */
  132. #endif
  133.     }
  134. }
  135.